洛谷题解 洛谷题解 题解:P10373 [AHOI2024 初中组] 立方根 xyx404 2024-04-21 2024-10-19
思路:
先通过此程序列出部分立方根向下取整的情况。
#include <bits/stdc++.h> using namespace std;long long s[20000000 ];long long jia (long long x,long long y) { long long sum=0 ; for (int i=x+1 ;i<=y;i++)sum+=cbrt (i); return sum; } int main () { long long x,y=0 ; long long last=0 ,las=0 ; for (int i=1 ;i<=1e6 ;i++){ s[i]=s[i-1 ]+cbrt (i); if (s[i]-s[i-1 ]!=last)cout<<i<<" " <<s[i]<<"\n" ,last=s[i]-s[i-1 ]; } return 0 ; }
可以发现每次当 i i i 为某数的立方时,立方根向下取整的结果会增加一。
所以我们可以定义一个变量 l l l 表示现在历遍的立方根,这样我们就不用从一历遍到十的十二次方了,只用历遍到十的十二次方的立方根了。
然后是如何计算,第一,当 l + 1 l+1 l + 1 的立方也就是下一个立方的值大于我们输入的 x + 1 x+1 x + 1 时,我们取较小的数,第二,当 l l l 的立方也就是现在的立方的值大于上一个输入的 x x x 的值时,我们在两个数取较大值,然后将 l + 1 l+1 l + 1 的立方和 x + 1 x+1 x + 1 的较小值与 l l l 的立方和上一个 x x x 的较大值相减,这样子做是为了防止多算和少算,然后总和加上就行了,循环条件是 l l l 的立方小于等于现在的 x x x 。
代码:
代码中的注释和思路里写的是一样的。
#include <bits/stdc++.h> using namespace std;#define ull unsigned long long ull T,x,l; ull f (ull n) { return n*n*n; } int main () { cin>>T; ull l=1 ,sum=0 ,last=0 ; for (ull i=1 ;i<=T;i++){ cin>>x; while (f (l)<=x){ sum+=l*((min (f (l+1 ),x+1 ))-max (f (l),last+1 )); l++; } l--; cout<<sum<<"\n" ; last=x; } return 0 ; }